<template>
  <el-dialog
    :title="formData.id ? '编辑接口' : '新建接口'"
    v-model="dialogVisible"
    width="800px"
    @close="handleClose"
  >
    <el-form
      ref="formRef"
      :model="formData"
      :rules="rules"
      label-width="120px"
      label-position="right"
    >
      <el-tabs v-model="activeTab">
        <el-tab-pane label="基本信息" name="basic">
          <el-form-item label="接口名称" prop="name">
            <el-input v-model="formData.name" placeholder="请输入接口名称" />
          </el-form-item>
          <el-form-item label="请求路径" prop="path">
            <el-input v-model="formData.path" placeholder="请输入请求路径" />
          </el-form-item>
          <el-form-item label="请求方法" prop="method">
            <el-select
              v-model="formData.method"
              placeholder="请选择请求方法"
              style="width: 100%"
            >
              <el-option
                v-for="method in Object.values(ApiMethod)"
                :key="method"
                :label="method"
                :value="method"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="接口类型" prop="type">
            <el-select
              v-model="formData.type"
              placeholder="请选择接口类型"
              style="width: 100%"
            >
              <el-option
                v-for="type in Object.values(ApiType)"
                :key="type"
                :label="getApiTypeLabel(type)"
                :value="type"
              />
            </el-select>
          </el-form-item>
          <el-form-item
            v-if="
              formData.type === ApiType.DataSource ||
              formData.type === 'database'
            "
            label="数据源"
            prop="dataSourceId"
          >
            <div v-if="DEBUG" class="debug-info">
              数据源数量: {{ dataSources.length }}, 加载中:
              {{ loadingDataSources }}, 当前选择: {{ formData.dataSourceId }}
            </div>
            <el-select
              v-model="formData.dataSourceId"
              placeholder="请选择数据源"
              :loading="loadingDataSources"
            >
              <el-option
                v-for="item in dataSources"
                :key="item.id"
                :label="item.name"
                :value="item.id"
              />
            </el-select>
            <div
              v-if="dataSources.length === 0 && !loadingDataSources"
              class="empty-tip"
            >
              <el-alert
                title="未找到可用的数据源"
                type="warning"
                :closable="false"
                show-icon
              >
                <template #default>
                  请先在<el-link type="primary" @click="goToDataSource"
                    >数据源管理</el-link
                  >中添加数据源
                </template>
              </el-alert>
            </div>
          </el-form-item>
          <el-form-item label="接口描述" prop="description">
            <el-input
              v-model="formData.description"
              type="textarea"
              :rows="3"
              placeholder="请输入接口描述"
            />
          </el-form-item>
        </el-tab-pane>

        <el-tab-pane label="接口配置" name="config">
          <!-- 数据源类型接口的配置 -->
          <div
            v-if="formData.type === ApiType.DataSource"
            class="datasource-config"
          >
            <h3>数据源接口配置</h3>
            <el-form-item label="数据源" prop="dataSourceId">
              <!-- 数据源选择器内容 -->
            </el-form-item>
            <!-- 其他数据源特有配置 -->
          </div>

          <!-- REST类型接口的配置 -->
          <div v-if="formData.type === ApiType.REST" class="rest-config">
            <h3>REST接口配置</h3>
            <!-- REST特有配置 -->
          </div>

          <!-- MagicAPI 配置 -->
          <template v-if="formData.type === ApiType.MagicAPI">
            <el-form-item label="SQL语句" prop="config.sql">
              <monaco-editor
                v-model="magicConfig.sql"
                language="sql"
                :height="200"
              />
            </el-form-item>
            <el-form-item label="参数配置">
              <monaco-editor
                v-model="paramsStr"
                language="json"
                :height="150"
                @change="handleParamsChange"
              />
            </el-form-item>
            <el-form-item label="缓存配置">
              <el-switch v-model="magicConfig.cache.enabled" class="mb-2" />
              <el-input-number
                v-if="magicConfig.cache.enabled"
                v-model="magicConfig.cache.timeout"
                :min="0"
                :step="1000"
                placeholder="缓存时间(ms)"
              />
            </el-form-item>
            <el-form-item label="分页配置">
              <el-switch v-model="magicConfig.page.enabled" class="mb-2" />
              <el-input-number
                v-if="magicConfig.page.enabled"
                v-model="magicConfig.page.pageSize"
                :min="1"
                :max="1000"
                placeholder="每页条数"
              />
            </el-form-item>
            <el-form-item label="事务控制">
              <el-switch v-model="magicConfig.transaction" />
            </el-form-item>
          </template>

          <!-- APIJSON 配置 -->
          <template v-else>
            <el-form-item label="请求结构">
              <el-form-item label="请求方法" prop="config.request.method">
                <el-select v-model="apijsonConfig.request.method">
                  <el-option label="GET" value="GET" />
                  <el-option label="HEAD" value="HEAD" />
                  <el-option label="POST" value="POST" />
                  <el-option label="PUT" value="PUT" />
                  <el-option label="DELETE" value="DELETE" />
                </el-select>
              </el-form-item>
              <el-form-item label="API版本" prop="config.request.version">
                <el-input v-model="apijsonConfig.request.version" />
              </el-form-item>
              <el-form-item label="结构定义">
                <monaco-editor
                  v-model="structureStr"
                  language="json"
                  :height="200"
                  @change="handleStructureChange"
                />
              </el-form-item>
            </el-form-item>

            <el-form-item label="查询配置">
              <el-form-item label="缓存">
                <el-switch v-model="apijsonConfig.query.cache" />
              </el-form-item>
              <el-form-item label="查询类型">
                <el-select v-model="apijsonConfig.query.type">
                  <el-option label="查询" value="QUERY" />
                  <el-option label="计数" value="COUNT" />
                  <el-option label="存在" value="EXISTS" />
                </el-select>
              </el-form-item>
              <el-form-item label="字段列表">
                <el-select
                  v-model="apijsonConfig.query.fields"
                  multiple
                  filterable
                  allow-create
                />
              </el-form-item>
            </el-form-item>

            <el-form-item label="访问控制">
              <el-form-item label="需要登录">
                <el-switch v-model="apijsonConfig.access.needLogin" />
              </el-form-item>
              <el-form-item label="角色限制">
                <el-select
                  v-model="apijsonConfig.access.role"
                  multiple
                  filterable
                  allow-create
                />
              </el-form-item>
            </el-form-item>
          </template>
        </el-tab-pane>

        <el-tab-pane label="参数定义" name="schema">
          <el-form-item label="请求参数" prop="requestSchema">
            <monaco-editor
              v-model="formData.requestSchema"
              language="json"
              :height="200"
            />
          </el-form-item>
          <el-form-item label="返回结构" prop="responseSchema">
            <monaco-editor
              v-model="formData.responseSchema"
              language="json"
              :height="200"
            />
          </el-form-item>
        </el-tab-pane>

        <!-- 添加预览标签页 -->
        <el-tab-pane label="预览" name="preview">
          <div class="preview-container">
            <div class="preview-header">
              <el-tag>{{ formData.method }}</el-tag>
              <span class="preview-path">{{ formData.path }}</span>
            </div>

            <el-divider>请求参数</el-divider>
            <monaco-editor
              v-model="requestPreview"
              language="json"
              :height="200"
              :options="{ readOnly: true }"
            />

            <el-divider>响应结果</el-divider>
            <monaco-editor
              v-model="responsePreview"
              language="json"
              :height="200"
              :options="{ readOnly: true }"
            />

            <div class="preview-footer">
              <el-button type="primary" @click="handleTest">测试接口</el-button>
              <el-button @click="handleCopyUrl">复制URL</el-button>
              <el-button @click="handleExportDoc">导出文档</el-button>
            </div>
          </div>
        </el-tab-pane>
      </el-tabs>
    </el-form>

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" @click="handleSubmit" :loading="submitting">
          确定
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, computed, watch, onMounted } from "vue";
import type { FormInstance, FormRules } from "element-plus";
import { ElMessage } from "element-plus";
import MonacoEditor from "@/components/MonacoEditor.vue";
import type { ApiConfig } from "@/types/api";
import {
  ApiMethod,
  ApiStatus,
  ApiType,
  type SqlConfig,
  type RestConfig,
  type MagicAPIConfig,
  type APIJSONConfig,
} from "@/types/api";
import type { DataSource } from "@/types/dataSource";
import { getDataSourceList } from "@/api/dataSource";
import { useRouter } from "vue-router";
import { PropType } from "vue";

const props = defineProps({
  visible: {
    type: Boolean,
    default: false,
  },
  editingData: {
    type: Object as PropType<ApiConfig | null>,
    default: null,
  },
  apiType: {
    type: String as PropType<ApiType | undefined>,
    default: undefined,
  },
  dataSources: {
    type: Array as PropType<DataSource[]>,
    default: () => [],
  },
  loadingDataSources: {
    type: Boolean,
    default: false,
  },
  loading: {
    type: Boolean,
    default: false,
  },
});

const emit = defineEmits<{
  (e: "update:visible", value: boolean): void;
  (e: "submit", data: ApiConfig): void;
}>();

const dialogVisible = computed({
  get: () => props.visible,
  set: (val) => emit("update:visible", val),
});

const formRef = ref<FormInstance>();
const submitting = ref(false);
const activeTab = ref("basic");
const dataSources = ref<DataSource[]>([]);
const sqlConfig = reactive<SqlConfig>({ sql: "" });
const restConfig = reactive<RestConfig>({
  url: "",
  method: ApiMethod.GET,
});

const sqlParamsStr = ref("{}");
const sqlParamsError = ref("");
const restHeadersStr = ref("{}");
const restHeadersError = ref("");
const restParamsStr = ref("{}");
const restParamsError = ref("");

const magicConfig = reactive<MagicAPIConfig>({
  sql: "",
  params: {},
  cache: {
    enabled: false,
    timeout: 60000,
  },
  page: {
    enabled: false,
    pageSize: 20,
  },
  transaction: false,
});

const apijsonConfig = reactive<APIJSONConfig>({
  request: {
    method: "GET",
    tag: "",
    version: "1.0",
    structure: {},
  },
  query: {
    cache: false,
    type: "QUERY",
    table: "",
    fields: [],
  },
  access: {
    role: [],
    needLogin: false,
  },
});

const defaultForm: Omit<ApiConfig, "id"> = {
  name: "",
  path: "",
  method: ApiMethod.GET,
  status: ApiStatus.Enabled,
  description: "",
  dataSourceId: 0,
  requestSchema: "{\n  \n}",
  responseSchema: "{\n  \n}",
};

const formData = reactive<ApiConfig>({ ...defaultForm });

const rules = reactive<FormRules>({
  name: [
    { required: true, message: "请输入接口名称", trigger: "blur" },
    { min: 2, max: 50, message: "长度在 2 到 50 个字符", trigger: "blur" },
  ],
  path: [
    { required: true, message: "请输入请求路径", trigger: "blur" },
    { pattern: /^\//, message: "路径必须以/开头", trigger: "blur" },
  ],
  method: [{ required: true, message: "请选择请求方法", trigger: "change" }],
  type: [{ required: true, message: "请选择接口类型", trigger: "change" }],
  dataSourceId: [
    {
      required: true,
      message: "请选择数据源",
      trigger: "change",
      type: "number",
    },
  ],
  "config.sql": [
    {
      required: true,
      message: "请输入SQL语句",
      trigger: "blur",
      type: "string",
    },
  ],
  "config.request.method": [
    { required: true, message: "请选择请求方法", trigger: "change" },
  ],
  "config.request.version": [
    { required: true, message: "请输入API版本", trigger: "blur" },
  ],
});

const getApiTypeLabel = (type: ApiType) => {
  const labels: Record<ApiType, string> = {
    [ApiType.DataSource]: "数据源接口",
    [ApiType.REST]: "REST接口",
    [ApiType.MagicAPI]: "MagicAPI 接口",
    [ApiType.APIJSON]: "APIJSON 接口",
  };
  return labels[type];
};

const loadDataSources = async () => {
  try {
    const { list } = await getDataSourceList({
      page: 1,
      pageSize: 1000,
    });
    dataSources.value = list;
  } catch (error) {
    console.error("加载数据源列表失败:", error);
  }
};

const handleJsonChange = (
  value: string,
  errorRef: Ref<string>,
  callback: (parsed: any) => void
) => {
  try {
    const parsed = JSON.parse(value);
    errorRef.value = "";
    callback(parsed);
  } catch (error) {
    errorRef.value = "JSON格式错误";
  }
};

const handleSqlParamsChange = (value: string) => {
  handleJsonChange(value, sqlParamsError, (parsed) => {
    sqlConfig.params = parsed;
  });
};

const handleRestHeadersChange = (value: string) => {
  handleJsonChange(value, restHeadersError, (parsed) => {
    restConfig.headers = parsed;
  });
};

const handleRestParamsChange = (value: string) => {
  handleJsonChange(value, restParamsError, (parsed) => {
    restConfig.params = parsed;
  });
};

const handleParamsChange = (value: string) => {
  handleJsonChange(value, sqlParamsError, (parsed) => {
    magicConfig.params = parsed;
  });
};

const handleStructureChange = (value: string) => {
  handleJsonChange(value, sqlParamsError, (parsed) => {
    apijsonConfig.request.structure = parsed;
  });
};

watch(
  () => props.editingData,
  (newVal) => {
    console.log("ApiForm - 编辑数据已更新:", newVal);
    if (newVal && newVal.type === "database") {
      console.log("当前编辑的是数据库类型 API，数据源ID:", newVal.dataSourceId);
    }
    if (newVal) {
      Object.assign(formData, newVal);
    } else {
      Object.assign(formData, defaultForm);
    }
  },
  { immediate: true }
);

watch(
  () => props.dataSources,
  (newVal) => {
    console.log("ApiForm - 数据源列表已更新:", newVal);
    dataSources.value = newVal;
  },
  { immediate: true }
);

watch(
  () => props.loadingDataSources,
  (newVal) => {
    console.log("ApiForm - 数据源加载状态已更新:", newVal);
  },
  { immediate: true }
);

const handleClose = () => {
  dialogVisible.value = false;
  formRef.value?.resetFields();
  Object.assign(formData, defaultForm);
  if (props.editingData && props.editingData.type) {
    formData.type = props.editingData.type;
  }
  sqlParamsError.value = "";
  restHeadersError.value = "";
  restParamsError.value = "";
  activeTab.value = "basic";
};

const handleSubmit = async () => {
  if (!formRef.value) return;

  if (sqlParamsError.value || restHeadersError.value || restParamsError.value) {
    ElMessage.error("请修正JSON格式错误");
    return;
  }

  await formRef.value.validate((valid) => {
    if (valid) {
      submitting.value = true;
      try {
        if (formData.type === ApiType.DataSource) {
          formData.config = { ...sqlConfig };
        } else if (formData.type === ApiType.MagicAPI) {
          formData.config = { ...magicConfig };
        } else if (formData.type === ApiType.APIJSON) {
          formData.config = { ...apijsonConfig };
        } else {
          formData.config = { ...restConfig };
        }
        emit("submit", { ...formData });
        handleClose();
      } finally {
        submitting.value = false;
      }
    }
  });
};

// SQL语法验证
const validateSql = (sql: string) => {
  // 简单的SQL语法检查
  const basicCheck = /^SELECT|INSERT|UPDATE|DELETE/i.test(sql.trim());
  if (!basicCheck) {
    return "SQL语句必须以SELECT/INSERT/UPDATE/DELETE开头";
  }
  return "";
};

// JSON Schema验证
const validateSchema = (schema: string) => {
  try {
    const parsed = JSON.parse(schema);
    if (typeof parsed !== "object") {
      return "Schema必须是一个JSON对象";
    }
    if (!parsed.type) {
      return "Schema必须包含type字段";
    }
    return "";
  } catch (error) {
    return "无效的JSON格式";
  }
};

// 预览相关的响应式数据
const requestPreview = computed(() => {
  if (formData.type === ApiType.MagicAPI) {
    return JSON.stringify(
      {
        sql: magicConfig.sql,
        params: magicConfig.params,
        options: {
          cache: magicConfig.cache,
          page: magicConfig.page,
          transaction: magicConfig.transaction,
        },
      },
      null,
      2
    );
  } else {
    return JSON.stringify(
      {
        request: apijsonConfig.request,
        query: apijsonConfig.query,
        access: apijsonConfig.access,
      },
      null,
      2
    );
  }
});

const responsePreview = ref("// 接口响应将显示在这里");

// 测试接口
const handleTest = async () => {
  try {
    responsePreview.value = "测试中...";
    const result = await testApi(formData);
    responsePreview.value = JSON.stringify(result, null, 2);
  } catch (error) {
    responsePreview.value = JSON.stringify(
      { error: "测试失败", message: error.message },
      null,
      2
    );
  }
};

// 复制URL
const handleCopyUrl = () => {
  const baseUrl = window.location.origin;
  const url = `${baseUrl}${formData.path}`;
  navigator.clipboard.writeText(url);
  ElMessage.success("URL已复制到剪贴板");
};

// 导出文档
const handleExportDoc = () => {
  const doc = {
    name: formData.name,
    description: formData.description,
    method: formData.method,
    path: formData.path,
    type: formData.type,
    request: JSON.parse(formData.requestSchema || "{}"),
    response: JSON.parse(formData.responseSchema || "{}"),
    config: formData.config,
  };

  const blob = new Blob([JSON.stringify(doc, null, 2)], {
    type: "application/json",
  });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = `${formData.name}.json`;
  a.click();
  URL.revokeObjectURL(url);
};

const router = useRouter();
const goToDataSource = () => {
  router.push("/data-source");
};

const initForm = () => {
  console.log("初始化API表单");

  // 重置表单为默认值
  Object.assign(formData, defaultForm);

  // 如果有编辑数据，填充表单
  if (props.editingData) {
    console.log("填充编辑数据:", props.editingData);
    Object.assign(formData, props.editingData);

    // 检查是否为数据库类型，确保 dataSourceId 正确设置
    if (props.editingData.type === ApiType.DataSource) {
      console.log(
        "当前编辑的数据源API，数据源ID:",
        props.editingData.dataSourceId
      );
    }
  } else if (props.apiType) {
    console.log("根据指定类型创建API:", props.apiType);
    formData.type = props.apiType;
  }
};

watch(
  () => props.visible,
  (val) => {
    if (val) {
      console.log("API表单对话框打开");
      initForm();
    }
  }
);

// 添加 watch 监控表单类型变化
watch(
  () => formData.type,
  (newType) => {
    console.log("表单类型变更为:", newType);

    // 根据类型重置特定配置
    if (newType === ApiType.DataSource) {
      // 重置数据源特定配置
      if (!formData.config) formData.config = {};
      // 设置默认配置
    } else if (newType === ApiType.REST) {
      // 重置REST特定配置
      if (!formData.config) formData.config = {};
      // 设置默认配置
    }
  },
  { immediate: true }
);

onMounted(() => {
  console.log("API表单组件已挂载");
  loadDataSources();
});
</script>

<style scoped>
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

.json-error {
  color: #f56c6c;
  font-size: 12px;
  margin-top: -15px;
  margin-bottom: 15px;
  padding-left: 120px;
}

:deep(.el-tabs__content) {
  overflow: visible;
}

.preview-container {
  padding: 20px;
  background-color: var(--el-bg-color-page);
  border-radius: 4px;
}

.preview-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 20px;
}

.preview-path {
  font-family: monospace;
  font-size: 16px;
  color: var(--el-text-color-primary);
}

.preview-footer {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

.empty-tip {
  margin-top: 10px;
  text-align: center;
}

.debug-info {
  margin-bottom: 10px;
  font-size: 12px;
  color: var(--el-text-color-secondary);
}

.datasource-config {
  /* 数据源接口配置的样式代码 */
}

.rest-config {
  /* REST接口配置的样式代码 */
}
</style> 